package net.esj.basic.dao.jdbc.impl;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import net.esj.basic.core.engine.config.MelonConfig;
import net.esj.basic.dao.Dao;
import net.esj.basic.dao.QueryBuilderDao;
import net.esj.basic.dao.jdbc.JdbcDao;
import net.esj.basic.dao.jdbc.JdbcSqlUtils;
import net.esj.basic.pojo.UpdateType;
import net.esj.basic.utils.Pagination;
import net.esj.basic.utils.Validators;
import net.melon.jdbc.JdbcTemplate;
import net.melon.jdbc.core.RowMapper;

public class JdbcDaoImpl extends JdbcQueryBuilderDaoImpl implements JdbcDao,QueryBuilderDao, Dao {
	
	@Override
	public <T> Pagination<T> queryPage(String sql, RowMapper<T> rowmapper,
			Pagination<T> page) {
		int total = getJdbcTemplate().queryForInt(JdbcSqlUtils.generateSelectCountSql(sql));
		page.setTotal(total);
		
		if(total==0){
			page.setSum(0);
		}else{
			page.setSum((total-1)/page.getRp()+1);
		}
		
		int start = (page.getPage() - 1) * page.getRp();
		int end = start + page.getRp();
		
		String pagesql =JdbcSqlUtils.generatePageSql(sql, start, page.getRp());
		
		List<T> list = getJdbcTemplate().query(pagesql, rowmapper);
		
		page.setRows(list);
		
		return page;
	}

	@Override
	public <T> Pagination<T> queryPage(String sql, RowMapper<T> rowmapper,
			Pagination<T> page, String order) {
		
		if(Validators.isEmpty(order)){
			if(sql.toUpperCase().contains("ORDER BY")){
				int i = sql.toUpperCase().lastIndexOf("ORDER BY");
				int j = sql.toUpperCase().lastIndexOf("ASC");
				int k = sql.toUpperCase().lastIndexOf("DESC");
				if(j>i){
					order = sql.substring(i, j+3);
				}else if(k>i){
					order = sql.substring(i, k+4);
				}
			}
		}
		
		int total = getJdbcTemplate().queryForInt(JdbcSqlUtils.generateSelectCountSql(sql));
		page.setTotal(total);
		
		if(total==0){
			page.setSum(0);
		}else{
			page.setSum((total-1)/page.getRp()+1);
		}
		
		int start = (page.getPage() - 1) * page.getRp();
		int end = start + page.getRp();
		
		
		String pagesql="";
		if(MelonConfig.getProperty("hibernate.dialect")!=null && MelonConfig.getProperty("hibernate.dialect").contains("MySQL")){
			pagesql = JdbcSqlUtils.generatePageSql(sql, start, page.getRp());
		}else{
			pagesql = JdbcSqlUtils.generatePageSql(sql, start, page.getRp(), order);
		}
		
		List<T> list = getJdbcTemplate().query(pagesql, rowmapper);
		
		page.setRows(list);
		
		return page;
	}

	@Override
	public <T> Pagination<T> queryPage(String sql, Object[] objs,
			RowMapper<T> rowmapper, Pagination<T> page) {
		int total = getJdbcTemplate().queryForInt(JdbcSqlUtils.generateSelectCountSql(sql),objs);
		page.setTotal(total);
		
		if(total==0){
			page.setSum(0);
		}else{
			page.setSum((total-1)/page.getRp()+1);
		}
		
		int start = (page.getPage() - 1) * page.getRp();
		int end = start + page.getRp();
		
		String pagesql = JdbcSqlUtils.generatePageSql(sql, start, end);
		
		List<T> list = getJdbcTemplate().query(pagesql,rowmapper,objs);
		
		page.setRows(list);
		
		return page;
	}

	@Override
	public <T> Pagination<T> queryPage(String sql, Object[] objs, int[] types,
			RowMapper<T> rowmapper, Pagination<T> page) {
		int total = getJdbcTemplate().queryForInt(JdbcSqlUtils.generateSelectCountSql(sql),objs,types);
		page.setTotal(total);
		
		if(total==0){
			page.setSum(0);
		}else{
			page.setSum((total-1)/page.getRp()+1);
		}
		
		int start = (page.getPage() - 1) * page.getRp();
		int end = start + page.getRp();
		
		String pagesql = JdbcSqlUtils.generatePageSql(sql, start, end);
		
		List<T> list = getJdbcTemplate().query(pagesql,rowmapper, objs,types);
		
		page.setRows(list);
		
		return page;
	}

	@Override
	public void delete(Object entity) {
		throw new RuntimeException("JDBC不支持当前方法");
	}

	@Override
	public void deleteAll(Collection c) {
		throw new RuntimeException("JDBC不支持当前方法");
	}

	@Override
	public <T> List<T> findAll(Class<T> clazz) {
		throw new RuntimeException("JDBC不支持当前方法");
	}

	@Override
	public <T> List<T> findAll(Class<T> clazz, boolean cachable) {
		throw new RuntimeException("JDBC不支持当前方法");
	}

	@Override
	public <T> T get(Serializable id, Class<T> clazz) {
		throw new RuntimeException("JDBC不支持当前方法");
	}

	@Override
	public void save(Object entity) {
		throw new RuntimeException("请不要用JDBC去新增数据");
	}

	@Override
	public void saveOrUpdate(Object entity) {
		throw new RuntimeException("请不要用JDBC去新增/修改数据");
	}

	@Override
	public void update(Object entity) {
		throw new RuntimeException("请不要用JDBC去修改数据");
	}

	@Override
	public void update(Object entity, UpdateType type) {
		throw new RuntimeException("请不要用JDBC去修改数据");
	}

	@Override
	public JdbcTemplate getJdbcTemplate() {
		return getSupportSource();
	}

	@Override
	public void execute(String executeStr) {
		getJdbcTemplate().execute(executeStr);
	}

	@Override
	public List query(String queryStr) {
		List list = getJdbcTemplate().queryForList(queryStr);
		return list;
	}

}
